#include "agency_service.h"
#include "context.h"
#include "streamdata.h"
#include "log.h"
#include "agencymgr.h"


static bool __init__ = AgencyService::Instance()->Init();

bool AgencyService::Init()
{
    Ctx.msg_router.BindMsg(agency_proto::AGENCY_CMD_GET_RESP, std::bind(&AgencyService::OnAgencyGet, this, std::placeholders::_1));
    return true;
}

bool AgencyService::HandleGetAgency(const std::string& name, std::string&& trans, Sence sence)
{
    StreamData stream_data;
    StreamDataWriter write(stream_data);
    write.Write<Sence>(sence);
    write.WriteString(trans);

    agency_proto::GetReq agency_get_req;
    agency_get_req.set_name(name);
    agency_get_req.set_trans(std::move(stream_data.Data()));
    Ctx.host->MtSendtoSrv(agency_proto::AGENCY_CMD_GET_REQ, SERVER_TYPE_AGENCY, &agency_get_req, 0);
    return true;
}

void AgencyService::OnAgencyGet(MsgData&& data)
{
    do
    {
        agency_proto::GetResp agency_get_resp;
        if (!agency_get_resp.ParseFromArray(data.data.c_str(), data.data.size()))
        {
            log_error("parser agency_proto::GetResp failed, stype:%d,svid:%d,uuid:%d", data.svtype, data.svid, data.uuid);
            break;
        }

        StreamData stream_data(std::move(*agency_get_resp.mutable_trans()));
        StreamDataReader reader(stream_data);
        Sence sence = reader.Read<Sence>();
        std::string trans = reader.ReadString();

        try
        {
            if (agency_get_resp.err_code() == 0)
            {
                stAgency agency;
                agency.CopyFrom(agency_get_resp.agency());
                AgencyMgr::Instance()->Update(std::move(agency));

                stAgency* p_agency = AgencyMgr::Instance()->Get(agency_get_resp.agency().name());
                OnSenceAgencyGet(sence, std::move(trans), agency_get_resp.err_code(), p_agency);
            }
            else
            {
                OnSenceAgencyGet(sence, std::move(trans), agency_get_resp.err_code(), nullptr);
            }
        }
        catch(const std::exception& e)
        {
            log_error("catch exception:%s, sence:%d, stype:%d,svid:%d,uuid:%d,msg:%s", e.what(), sence, data.svtype, data.svid, data.uuid, agency_get_resp.ShortDebugString().c_str());
        }
        catch(...)
        {
            log_error("catch unknown exception, sence:%d, stype:%d,svid:%d,uuid:%d,msg:%s", sence, data.svtype, data.svid, data.uuid, agency_get_resp.ShortDebugString().c_str());
        }
    } while(false);
}

void AgencyService::OnSenceAgencyGet(Sence sence, std::string&& trans, std::int32_t err_code, stAgency* agency)
{
    auto it = m_agencyuser_get_listen.find(sence);
    if (it == m_agencyuser_get_listen.end())
    {
        log_warning("sence:%d not listen", sence);
        return;
    }
    it->second(err_code, agency, std::move(trans));
}



